package cn.t.repository.impl.order;

import cn.t.constants.ParamConstants;
import cn.t.converter.order.OrderDetailConverter;
import cn.t.core.repoistory.RepositoryImpl;
import cn.t.dto.order.QuotationQueryRequest;
import cn.t.model.order.OrderDetailDO;
import cn.t.persistence.entity.order.OrderDetailPO;
import cn.t.persistence.mapper.order.OrderDetailMapper;
import cn.t.repository.order.OrderDetailRepository;
import cn.t.utils.DateUtil;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 领料订单明细表(OrderDetail)数据仓库
 *
 * @author t
 * @since 2024-05-24 10:18:10
 */
@Slf4j
@Repository
@AllArgsConstructor
public class OrderDetailRepositoryImpl extends RepositoryImpl<OrderDetailMapper, OrderDetailPO, OrderDetailConverter, OrderDetailDO> implements OrderDetailRepository {


    @Override
    public List<OrderDetailDO> findByModel(OrderDetailDO orderDetailDO, int start, Integer pageSize, String field, String direction) {

        String lastSql = getLastSql(start, pageSize, field, direction);

        List<OrderDetailPO> list = getWrapper(orderDetailDO)
                .last(lastSql)
                .list();
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }

        return list.stream().map(converter::po2Model).collect(Collectors.toList());
    }
    private static String getLastSql(int start, Integer pageSize, String field, String direction) {
        return StringUtils.hasText(field) ?
                " order by " + field +" "+ direction + " limit " + start + "," + pageSize
                :
                " limit " + start + "," + pageSize;
    }

    private LambdaQueryChainWrapper<OrderDetailPO> getWrapper(OrderDetailDO orderDetailDO) {
        LambdaQueryChainWrapper<OrderDetailPO> wrapper = lambdaQuery();
        if (!ObjectUtils.isEmpty(orderDetailDO.getOrderSn())) {
            wrapper.eq(OrderDetailPO::getOrderSn, orderDetailDO.getOrderSn());
        }
        if (!ObjectUtils.isEmpty(orderDetailDO.getOrderSnList())) {
            wrapper.in(OrderDetailPO::getOrderSn, orderDetailDO.getOrderSnList());
        }
        if (!ObjectUtils.isEmpty(orderDetailDO.getIds())) {
            wrapper.in(OrderDetailPO::getId, orderDetailDO.getIds());
        }
        if (!ObjectUtils.isEmpty(orderDetailDO.getSkuCode())) {
            wrapper.eq(OrderDetailPO::getSkuCode, orderDetailDO.getSkuCode());
        }
        if (!ObjectUtils.isEmpty(orderDetailDO.getSkuCodes())) {
            wrapper.in(OrderDetailPO::getSkuCode, orderDetailDO.getSkuCodes());
        }
        if (!ObjectUtils.isEmpty(orderDetailDO.getSkuName())) {
            wrapper.eq(OrderDetailPO::getSkuName, orderDetailDO.getSkuName());
        }
        if (!ObjectUtils.isEmpty(orderDetailDO.getQty())) {
            wrapper.eq(OrderDetailPO::getQty, orderDetailDO.getQty());
        }
        if (!ObjectUtils.isEmpty(orderDetailDO.getBeforeWeight())) {
            wrapper.eq(OrderDetailPO::getBeforeWeight, orderDetailDO.getBeforeWeight());
        }
        if (!ObjectUtils.isEmpty(orderDetailDO.getAfterWeight())) {
            wrapper.eq(OrderDetailPO::getAfterWeight, orderDetailDO.getAfterWeight());
        }
        if (!ObjectUtils.isEmpty(orderDetailDO.getCargowayId())) {
            wrapper.eq(OrderDetailPO::getCargowayId, orderDetailDO.getCargowayId());
        }
        if (!ObjectUtils.isEmpty(orderDetailDO.getOrderTransferStatus())) {
            wrapper.eq(OrderDetailPO::getOrderTransferStatus, orderDetailDO.getOrderTransferStatus());
        }
        if (!ObjectUtils.isEmpty(orderDetailDO.getErrorRate())) {
            wrapper.eq(OrderDetailPO::getErrorRate, orderDetailDO.getErrorRate());
        }
        if (!ObjectUtils.isEmpty(orderDetailDO.getStdWeight())) {
            wrapper.eq(OrderDetailPO::getStdWeight, orderDetailDO.getStdWeight());
        }
        if (!ObjectUtils.isEmpty(orderDetailDO.getGmtModified())) {
            wrapper.between(OrderDetailPO::getGmtModified, orderDetailDO.getGmtModifiedStart(), orderDetailDO.getGmtModifiedEnd());
        }
        if (!ObjectUtils.isEmpty(orderDetailDO.getGmtCreated())) {
            wrapper.between(OrderDetailPO::getGmtCreated, orderDetailDO.getGmtCreatedStart(), orderDetailDO.getGmtCreatedEnd());
        }
        return wrapper;
    }
    private LambdaQueryChainWrapper<OrderDetailPO> getQueryWrapper(QuotationQueryRequest detailDo, List<String> orderSnList) {
        LambdaQueryChainWrapper<OrderDetailPO> wrapper = lambdaQuery();
        wrapper.in(!ObjectUtils.isEmpty(detailDo.getSkuList()),OrderDetailPO::getSkuCode, detailDo.getSkuList());
        wrapper.notIn(!ObjectUtils.isEmpty(detailDo.getNoSkuList()),OrderDetailPO::getSkuCode, detailDo.getNoSkuList());
        if (detailDo.getFaExclude() != null && detailDo.getFaExclude() == 0) {
            wrapper.notLike(OrderDetailPO::getSkuCode, "FA");
        }
        if (!ObjectUtils.isEmpty(detailDo.getOrderSnList())) {
            wrapper.in(OrderDetailPO::getOrderSn, detailDo.getOrderSnList());
        }
        if (org.apache.commons.lang3.ObjectUtils.isNotEmpty(detailDo.getSkuName())) {
            wrapper.like(OrderDetailPO::getSkuName,detailDo.getSkuName().trim() );
        } if (org.apache.commons.lang3.ObjectUtils.isNotEmpty(detailDo.getSkuCode())) {
            wrapper.eq(OrderDetailPO::getSkuName,detailDo.getSkuCode().trim() );
        }

        wrapper.in(OrderDetailPO::getOrderSn, orderSnList);
        return wrapper;
    }
    @Override
    public List<OrderDetailDO> queryOrderDetailList(QuotationQueryRequest detailDo, List<String> orderSnList, int start, Integer pageSize, String field, String direction) {
        String lastSql = getLastSql(start, pageSize, field, direction);
        List<OrderDetailPO> list = getQueryWrapper(detailDo,orderSnList).last(lastSql).list();
        return converter.po2DoList(list);
    }
    @Override
    public List<OrderDetailDO> queryDetailByUserFirm(Long userId, Long firmId, List<String> skuCodes, Date timeStart) {
        OrderDetailDO orderDetailDO = new OrderDetailDO();
        orderDetailDO.setSkuCodes(skuCodes);
        LambdaQueryChainWrapper<OrderDetailPO> wrapper = getWrapper(orderDetailDO);
        List<OrderDetailPO> list = wrapper.inSql(OrderDetailPO::getOrderSn, "select order_sn from t_order where user_id = " + userId + " and firm_id = " + firmId + " and gmt_close >= '" + DateUtil.getDateStr(timeStart) + "'").list();
        if (list.isEmpty()) {
            return new ArrayList<>();
        }
        return converter.po2DoList(list);
    }
    public Long queryOrderDetailCount(QuotationQueryRequest detailDo, List<String> orderSnList) {
        return getQueryWrapper(detailDo,orderSnList).count();
    }
    private LambdaUpdateChainWrapper<OrderDetailPO> getUpdateWrapper(OrderDetailDO orderDetailDO) {
        LambdaUpdateChainWrapper<OrderDetailPO> wrapper = lambdaUpdate();
        if (!ObjectUtils.isEmpty(orderDetailDO.getOrderSn())) {
            wrapper.eq(OrderDetailPO::getOrderSn, orderDetailDO.getOrderSn());
        }
        if (!ObjectUtils.isEmpty(orderDetailDO.getId())) {
            wrapper.eq(OrderDetailPO::getId, orderDetailDO.getId());
        }

        if (!ObjectUtils.isEmpty(orderDetailDO.getSkuCode())) {
            wrapper.set(OrderDetailPO::getSkuCode, orderDetailDO.getSkuCode());
        }
        if (!ObjectUtils.isEmpty(orderDetailDO.getSkuName())) {
            wrapper.set(OrderDetailPO::getSkuName, orderDetailDO.getSkuName());
        }
        if (!ObjectUtils.isEmpty(orderDetailDO.getQty())) {
            wrapper.set(OrderDetailPO::getQty, orderDetailDO.getQty());
        }
        if (!ObjectUtils.isEmpty(orderDetailDO.getStdWeight())) {
            wrapper.set(OrderDetailPO::getStdWeight, orderDetailDO.getStdWeight());
        }

        if (!ObjectUtils.isEmpty(orderDetailDO.getQty())) {
            wrapper.set(OrderDetailPO::getQty, orderDetailDO.getQty());
        }
        if (!ObjectUtils.isEmpty(orderDetailDO.getStdWeight())) {
            wrapper.set(OrderDetailPO::getStdWeight, orderDetailDO.getStdWeight());
        }
        if (!ObjectUtils.isEmpty(orderDetailDO.getIsDeleted())) {
            wrapper.set(OrderDetailPO::getIsDeleted, orderDetailDO.getIsDeleted());
        }
        return wrapper;
    }
    @Override
    public long count(OrderDetailDO orderDetailDO) {
        return getWrapper(orderDetailDO).count();
    }

    @Override
    public Boolean addOrUpdateBatch(List<OrderDetailDO> orderDetailList) {
        List<OrderDetailPO> orderDetails = converter.do2PoList(orderDetailList);
       return  saveOrUpdateBatch(orderDetails, ParamConstants.INT_2000);
    }

    @Override
    public Boolean updateModel(OrderDetailDO orderDetailDO,List<Long> ids) {
        LambdaUpdateChainWrapper<OrderDetailPO> updateWrapper = getUpdateWrapper(orderDetailDO);
        updateWrapper.in(!CollectionUtils.isEmpty(ids),OrderDetailPO::getId,ids);
        return baseMapper.update(null, updateWrapper.getWrapper())>0;
    }
}
